﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//int main()
//{
//	//short age = 20;//向内存申请2个字节的空间来存放20
//	//float weight = 95.5F;//向内存申请4个字节的空间来存放95.5
//	int a = 20;
//	int* pa = &a;
//	//*pa = 200;//找到pa存放的a的地址，将其改为200 ，等价于a = 200
//	//printf("%d\n", a);//200
//	return 0;
//}

//int main()
//{
//	char ch = 'w';
//	char* pc = &ch;
//	//sizeof：计算使⽤类型创建的变量所占内存空间的⼤⼩,单位是字节
//	printf("%zd\n", sizeof(pc));
//	//x64环境下，结果为8   x86环境下，结果为4
//	return 0;
//}

//int main()
//{
//	int a = 0x11223344;
//	char* pa = &a;//将拿到的a的地址存到字符型指针变量pa中
//	*pa = 0;//修改pa指向的变量a 的值
//
//	return 0;
//}

//int main()
//{
//	int a = 0x11223344;
//	int* pa = &a;
//	char* pc = &a;
//
//	printf("%p\n", &a);
//	printf("%p\n", pa);
//	printf("%p\n", pc);
//	//上面三个打印出的结果相同
//	
//	printf("%p\n", &a + 1);//跳过4个字节
//	printf("%p\n", pa + 1);//跳过4个字节
//	printf("%p\n", pc + 1);//跳过1个字节，得到a的第2个字节的地址
//
//	return 0;
//}

//int main()
//{
//	int a = 10;
//	char ch = 'a';
//
//	void* pv1 = &a;//&a类型为int*
//	void* pv2 = &ch;//&ch类型为char*
//
//	return 0;
//}

//int main()
//{
//	//const int num = 20;//num具有了常量的属性，num的值不能被修改
//	//num = 30;//报错
//
//	int n = 10;
//	//C99之前不支持变长数组，数组的大小需要 常量或常量表达式 来指定
//	//不能用变量来指定
//	int arr[n];//报错
//
//	const int n = 10;// n被const修饰后，本质上还是变量
//	int arr[n];//报错
//
//	return 0;
//}

//int main()
//{
//	const int n = 10;
//	//n = 200; 无法修改
//	int* p = &n;
//	*p = 200;//n = 200 可以修改
//	printf("%d\n", n);//200
//
//	return 0;
//}

//int main()
//{
//	int n = 10;
//	int m = 100;
//	
//	//const同时在 * 的左右两边修饰
//	const int* const p = &n;
//	*p = 200;//err
//    p = &m;//err
//	
//	//int const * p = &n;
//
//	//*p = 20;//报错
//	//*p = 20;
//	return 0;
//}

//野指针
// 1.指针未初始化
//int main()
//{
//	int* p;//指针未初始化
//	*p = 20;
//
//	return 0;
//}


//指针越界访问
//int main()
//{
//	int arr[10] = { 0 };
//	int* p = &arr[0];//取出数组arr的第一个元素的地址
//	for (int i = 0; i <= 10; i++)
//	{
//		*p = i;//当 i = 10的时候，p越界访问arr[10]这块空间，此时p就是野指针
//		p++;
//	}
//	return 0;
//}

//非法访问

//int test()
//{
//	int n = 100;//进入函数，开辟一块空间存放n
//	return &n;//n的地址返回
//}//出函数，n的空间被销毁
//int main()
//{
//	int* p = test();//调用test函数，p得到n的地址
//	printf("%d\n", *p);
//
//	return 0;
//}

//int main()
//{
//	//int a = 10;
//	//int* p = &a;//有明确的指向
//
//	//int* p2 = NULL;//没有明确的指向，赋值NULL
//
//	//int a = 10;
//	//int* p = &a;
//	//p = NULL;
//	//if (p != NULL)//p不是空指针时，才对p进行解引用操作
//	//{
//	//	*p = 200;
//	//}
//
//	return 0;
//}

//#define NDEBUG
//#include<assert.h>
//int main()
//{
//	int* p = NULL;
//	assert(p != NULL);//定义了NEDBUG宏后，assert失效，不会报错
//
//	return 0;
//}

//指针运算
int main()
{
	//int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//int sz = sizeof(arr) / sizeof(arr[0]);//计算数组有几个元素
	//int* p = &arr[0];//取出数组首元素的地址存到 p 里面
	//for (int i = 0; i < sz; i++)
	//{
	//	printf("%d ", *p);//
	//	p++;//
	//}

	//int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//printf("%d\n", &arr[9] - &arr[0]);//9
	//printf("%d\n", &arr[9] - &arr[0]);//-9
	

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组有几个元素
	int* p = &arr[0];//取出数组首元素的地址存到 p 里面

    //打印数组里的每个元素
	while (p < &arr[sz])//两个地址相比较
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}